#! /usr/bin/env python
# -*- coding:utf-8 -*-
# Author Jmz

class Mymeta(type):
    __instance = None
    def __init__(self,class_name,class_bases,class_dict):
        if not class_name.istitle:
            raise TypeError("类的首字母必须大写")
        if not class_dict.get("__doc__"):
            raise TypeError("类的创建需写入注释说明")

        super(Mymeta,self).__init__(class_name,class_bases,class_dict)

    def __call__(self, *args, **kwargs):   # __call__  是由类调用的，所以self 就是类本身
        # 1、 产生一个空对象
        # 2、 将参数传入类的__init___方法中
        if not self.__instance:
            obj = object.__new__(self)   # 产生一个空对象,, __new__ 是object 的静态方法
            self.__init__(obj,*args,**kwargs)  # 调用类的__init__ 方法，self 就是类
            self.__instance = obj
        return self.__instance

class Student(object,metaclass=Mymeta):
    '''
    学生类
    '''
    def __init__(self,name,age,school):
        self.name = name
        self.age = age
        self.school = school

    def learn(self,thing):
        print("%s 正在学习%s"%(self.name,thing))

class Teacher(object,metaclass=Mymeta):
    '''
    老师类
    '''
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def teach(self,):
        print("%s 正在教书中。。。"%self.name)


jmz = Student("jmz",23,"北大")
jmz1 = Student("jmz1",23,"北大")

print(id(jmz),id(jmz1))
# 38853264 38853264


egon = Teacher("egon",24)
egon1 = Teacher("egon1",24)
print(id(egon),id(egon1))
# 31578992 31578992



# 解释
# 1、student 类和 teacher类都是调用元类产生的，不同的类调用元类就好产生不同的内容地址。不同的类也只会定义一次（正常的）
# 2、 对象的产生是有调用了元类的__call__ 方法产生的，所以每次调用都返回相同的对象（单例）。
